Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(prometheus): add getMetricsRequestHandler-method to Prometheus #1879

Merged
merged 11 commits into from
Feb 8, 2021

Conversation

weyert
Copy link
Contributor

@weyert weyert commented Jan 27, 2021

… exporter

This commit introduces a new method on the PrometheusExporter-class that
allows users of server frameworks with an existing service instance to
call the getMetricsRequestHandler-method as part of a route to return
the collected metrics in Prometheus format.

Fixes #1872

Which problem is this PR solving?

  • Allows using an existing server instance to expose the Prometheus endpoint / metrics

Short description of the changes

  • Added a new getMetricsRequestHandler-method to the PrometheusExporter-class which calls the internal _exportMetrics-method

… exporter

This commit introduces a new method on the `PrometheusExporter`-class that
allows users of server frameworks with an existing service instance to
call the `getMetricsRequestHandler`-method as part of a route to return
the collected metrics in Prometheus format.
@linux-foundation-easycla
Copy link

linux-foundation-easycla bot commented Jan 27, 2021

CLA Signed

The committers are authorized under a signed CLA.

@codecov
Copy link

codecov bot commented Jan 27, 2021

Codecov Report

Merging #1879 (2a74584) into main (9cfa92c) will decrease coverage by 0.01%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##             main    #1879      +/-   ##
==========================================
- Coverage   92.74%   92.73%   -0.02%     
==========================================
  Files         173      173              
  Lines        5971     5973       +2     
  Branches     1269     1269              
==========================================
+ Hits         5538     5539       +1     
- Misses        433      434       +1     
Impacted Files Coverage Δ
...etry-exporter-prometheus/src/PrometheusExporter.ts 92.53% <100.00%> (+0.22%) ⬆️
...ges/opentelemetry-instrumentation-http/src/http.ts 94.73% <0.00%> (-0.81%) ⬇️
...emetry-core/src/platform/node/RandomIdGenerator.ts 93.75% <0.00%> (+6.25%) ⬆️

@vmarchaud
Copy link
Member

@weyert You need to sign the CLA (you can follow the bot message to approve it) and also the lint CI fails because of an unrelated problem so you can ignore it

@weyert
Copy link
Contributor Author

weyert commented Jan 28, 2021

I have updated the tests so it uses sinon to do the mocking for my unit test.

@weyert
Copy link
Contributor Author

weyert commented Jan 28, 2021

@weyert You need to sign the CLA (you can follow the bot message to approve it) and also the lint CI fails because of an unrelated problem so you can ignore it

Yes, I am going through the easycla process :)

@weyert
Copy link
Contributor Author

weyert commented Jan 29, 2021

@vmarchaud I have promoted the pull request. It's not a draft anymore

* @param request Incoming HTTP request of server instance
* @param response HTTP response objet used to response to request
*/
public getMetricsRequestHandler(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function names implies you are getting a handler, which is not the what is actually happening. I think it would be smarter to return a middleware that is compatible with express and other web frameworks:

public getMetricsRequestHandler() {
  const self = this;
  return function metricsHandler(req, res, next) {
	// req validation?
    // suppress instrumenting this method? optionally?
	// error handling?	

    self.exportMetrics(res);
  };
}

Copy link
Contributor Author

@weyert weyert Jan 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea I was having to return a raw handler which has the IncomingMessage, and ServerResponse arguments as we can't really be sure what the user's framework is. I was thinking the user could do something like this for Express:

app.get('/metrics', (req, res) => {
    return exporter.getMetricsRequestHandler(req, res)
})

while for Hapi you could do something like:

function HapiWrapper(exporter) {
    const handler = exporter.getMetricsRequestHandler()
    return async ( { raw }, h) {
         await handler(raw.req, raw.res)
         return h.close
    } 
}

while for Koa something like:

const router = app.router()
router.get('/metrics', async (ctx) => {
   await handle(ctx.req, ctx.res)
   ctx.respond = false
})

Probably would need to allow the handler to be async but the above the idea to offer most flexibility. Maybe the name needs to better reflect this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But you have a point maybe it should be returned with .bind(this)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @weyert here, its better to use a simpler model that doesn't necessarely match express api so it can be used with every framework (at the cost of having a different usage)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @vmarchaud :)

@weyert
Copy link
Contributor Author

weyert commented Feb 3, 2021

Does anyone understand why it complains about sinon and @types/sinon-packages while I have added it to package.json?

@dyladan
Copy link
Member

dyladan commented Feb 3, 2021

Does anyone understand why it complains about sinon and @types/sinon-packages while I have added it to package.json?

Because you have not regenerated the package-lock.json files. If you delete the file then bootstrap again it will be fixed.

@weyert
Copy link
Contributor Author

weyert commented Feb 3, 2021

Does anyone understand why it complains about sinon and @types/sinon-packages while I have added it to package.json?

Because you have not regenerated the package-lock.json files. If you delete the file then bootstrap again it will be fixed.

Yes, I did regenerate it but the lock file is being ignored in .gitignore?

# lock files
yarn.lock
package-lock.json
packages/**/yarn.lock
packages/**/package-lock.json

@weyert
Copy link
Contributor Author

weyert commented Feb 3, 2021

Oh it changed recently :)

Copy link
Member

@obecny obecny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm,
just please remove package-lock.json it is no longer needed

@dyladan dyladan added the enhancement New feature or request label Feb 5, 2021
@weyert
Copy link
Contributor Author

weyert commented Feb 7, 2021

lgtm,
just please remove package-lock.json it is no longer needed

Hmm, yeah, I had issues with it earlier. I will have a look at it tomorrow :)

@weyert
Copy link
Contributor Author

weyert commented Feb 8, 2021

@obecny I have made your requested change. I did goof up a bit while doing it (deleted wrong file) but should be sorted now

@vmarchaud vmarchaud merged commit a299b1d into open-telemetry:main Feb 8, 2021
@vmarchaud
Copy link
Member

@weyert Thanks for the contribution !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Expose request handler of Prometheus exporter
5 participants